package public_C

import (
	"Student_Mental/DBconfing"
	"Student_Mental/model"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis"
	"os"
	"strconv"
	"strings"
	"time"
)

func returnErr(err error, c *gin.Context) {
	if err != nil {
		c.JSON(200, gin.H{
			"code": 1,
			"msg":  err.Error(),
		})
	}
}

// EditPassword
// @Tags 公共
// @summary 修改密码
// @Param id path  string false "学生或老师ID"
// @Param Status formData  string false "状态：老师/学生"
// @Param password formData  string false "新密码"
// @Success 200 {string} json{"code","id","Status","password","msg","icon"}
// @Router /EditPassword/{id} [post]
func EditPassword(c *gin.Context) {
	id := c.Param("id")
	Status := c.PostForm("Status")
	password := c.PostForm("password")
	sqlDb, _ := DBconfing.Mysql()
	var rowCount int64
	if password == "" {
		c.JSON(200, gin.H{
			"code": -1,
			"msg":  "密码为空",
			"icon": -1,
		})
	} else {
		if Status == "老师" {
			rs, err := sqlDb.Exec("update teacher set teacher_password=? where id=?", password, id)
			returnErr(err, c)
			rowCount, err = rs.RowsAffected()
			returnErr(err, c)

		} else {
			rs, err := sqlDb.Exec("update student set student_password=? where id=?", password, id)
			returnErr(err, c)
			rowCount, err = rs.RowsAffected()
			returnErr(err, c)
		}
		if rowCount > 0 {
			c.JSON(200, gin.H{
				"code":     0,
				"id":       id,
				"Status":   Status,
				"password": password,
				"msg":      "修改成功",
				"icon":     1,
			})
		} else {
			c.JSON(200, gin.H{
				"code": -1,
				"msg":  "修改失败",
				"icon": -1,
			})
		}
	}
	sqlDb.Close()
}

// Information
// @Tags 公共
// @summary 获取个人信息
// @Param id path  string false "学生或老师ID"
// @Param Status path  string false "状态：老师/学生"
// @Success 200 {string} json{"id","status","data"}
// @Router /public/information/{status}/{id} [get]
func Information(c *gin.Context) {
	id := c.Param("id")
	Status := c.Param("status")
	sqlDb, _ := DBconfing.Mysql()

	if Status == "1" {
		var s model.Teacher
		sqlDb.QueryRow("SELECT teacher_name,teacher_number,teacher_sex,teacher_age,avatar,booking_place FROM teacher where id=?", id).Scan(&s.Name, &s.Number, &s.Sex, &s.Age, &s.Avatar, &s.BookingPlace)
		c.HTML(200, "Information.html", gin.H{
			"id":     id,
			"status": Status,
			"data":   s,
		})

	} else {
		var s model.Student
		sqlDb.QueryRow("SELECT * FROM student where id=?", id).Scan(&s.Id, &s.ClassId, &s.MajorId, &s.Number, &s.Password, &s.Name, &s.Sex, &s.Age, &s.CreateTime, &s.Avatar)
		c.HTML(200, "Information.html", gin.H{
			"id":     id,
			"status": Status,
			"data":   s,
		})
	}
	sqlDb.Close()
}

// InformationEdit
// @Tags 公共
// @summary 修改个人信息
// @Param id path  string false "学生或老师ID"
// @Param Status path  string false "状态：老师/学生"
// @Param Name formData  string false "名字"
// @Param Sex formData  string false "性别"
// @Param Age formData  string false "年龄"
// @Success 200 {string} json{"code","msg","icon"}
// @Router /public/informationEdit/{Status}/{id} [get]
func InformationEdit(c *gin.Context) {
	id := c.Param("id")
	Status := c.Param("Status")
	Name := c.PostForm("Name")
	Sex := c.PostForm("Sex")
	Age := c.PostForm("Age")
	bookingPlace := c.PostForm("booking_place")
	sqlDb, _ := DBconfing.Mysql()
	var rowCount int64
	if Status == "老师" {
		rs, err := sqlDb.Exec("update teacher set teacher_name=?,teacher_sex=?,teacher_age=?,booking_place=? where id=?", Name, Sex, Age, bookingPlace, id)
		returnErr(err, c)
		rowCount, err = rs.RowsAffected()
		returnErr(err, c)
	} else if Status == "学生" {
		rs, err := sqlDb.Exec("update student set student_name=? where id=?", Name, id)
		returnErr(err, c)
		rowCount, err = rs.RowsAffected()
		returnErr(err, c)
	}
	if rowCount > 0 {
		c.JSON(200, gin.H{
			"code": 0,
			"msg":  "修改成功",
			"icon": 1,
		})
	} else {
		c.JSON(200, gin.H{
			"code": -1,
			"msg":  "修改失败",
			"icon": -1,
		})
	}
	sqlDb.Close()
}

// UploadAvatar
// @Tags 公共
// @summary 上传头像
// @Router /public/upload/{id} [get]
func UploadAvatar(c *gin.Context) {
	file, _ := c.FormFile("file")
	id := c.PostForm("id")
	Status := c.PostForm("Status")
	var filename string
	if Status == "老师" {
		filename = "teacher/" + id + ".png"
	} else if Status == "学生" {
		filename = "student/" + id + ".png"
	}

	if err := c.SaveUploadedFile(file, "./static/images/avatar/"+filename); err != nil {
		c.JSON(200, gin.H{
			"err": err.Error(),
		})
		return
	}
	sqlDb, _ := DBconfing.Mysql()
	if Status == "老师" {
		var filePath = "/static/images/avatar/" + filename
		_, err := sqlDb.Exec("update teacher set avatar=? where id=?", filePath, id)
		returnErr(err, c)
	} else if Status == "学生" {
		var filePath = "/static/images/avatar/" + filename
		_, err := sqlDb.Exec("update student set avatar=? where id=?", filePath, id)
		returnErr(err, c)
	}
	c.JSON(200, gin.H{
		"file": file,
		"id":   id,
		"msg":  "成功",
		"icon": 1,
	})
	sqlDb.Close()
}

// UploadMessageImg 上传聊天图片
func UploadMessageImg(c *gin.Context) {
	sqlDb, _ := DBconfing.Mysql()
	defer sqlDb.Close()
	file, _ := c.FormFile("file")
	id := c.PostForm("id")
	roomId := c.PostForm("roomId")
	fmt.Println(roomId)
	filename := id + ".png"
	filePath := "./static/images/room/" + roomId
	if _, err := os.Stat(filePath); os.IsNotExist(err) {
		// 如果路径不存在，则创建路径
		if err := os.MkdirAll(filePath, 0777); err != nil {
			fmt.Println(err)
			return
		}
	}
	if err := c.SaveUploadedFile(file, filePath+"/"+filename); err != nil {
		c.JSON(200, gin.H{
			"err": err.Error(),
		})
		return
	}
	//var filePath = "/static/images/" + filename
	//_, err := sqlDb.Exec("update student set avatar=? where id=?", filePath, id)
	//returnErr(err, c)
	c.JSON(200, gin.H{
		"file": file,
		"id":   id,
		"msg":  "成功",
		"icon": 1,
	})
}

// UploadCarousel 上传轮播图
func UploadCarousel(c *gin.Context) {
	sqlDb, _ := DBconfing.Mysql()
	defer sqlDb.Close()
	file, _ := c.FormFile("file")
	id := c.PostForm("id")
	filename := "carousel/" + id + ".png"
	if err := c.SaveUploadedFile(file, "./static/images/"+filename); err != nil {
		c.JSON(200, gin.H{
			"err": err.Error(),
		})
		return
	}
	var filePath = "/static/images/" + filename
	_, err := sqlDb.Exec("update student set avatar=? where id=?", filePath, id)
	returnErr(err, c)
	c.JSON(200, gin.H{
		"file": file,
		"id":   id,
		"msg":  "成功",
		"icon": 1,
	})
}

// GetAvatar
// @Tags 公共
// @summary 获取头像
// @Param id path  string false "学生或老师ID"
// @Router /public/getAvatar/{id} [get]
func GetAvatar(c *gin.Context) {
	Id := c.Param("id")
	red, _ := DBconfing.ConnRedis()
	defer red.Close()
	var avatar string
	value, _ := red.HGet("avatar", Id).Result()
	if value != "" {
		avatar = value
	} else {
		sqlDb, _ := DBconfing.Mysql()
		defer sqlDb.Close()
		sqlDb.QueryRow("(SELECT avatar FROM student WHERE id = ?)UNION(SELECT avatar FROM teacher WHERE id = ?)LIMIT 1;", Id, Id).Scan(&avatar)
		if avatar != "" {
			// 将值存储在 hash 中
			err := red.HSet("avatar", Id, avatar).Err()
			if err != nil {
				panic(err)
			}
		}
	}

	c.JSON(200, gin.H{
		"code":   200,
		"Id":     Id,
		"avatar": avatar,
	})
}

// GetUnread
// @Tags 公共
// @summary 获取未读消息
// @Param id formData string false "学生或老师ID"
// @Router /public/msg/getUnread [post]
func GetUnread(c *gin.Context) {
	Id := c.PostForm("id")
	red, _ := DBconfing.ConnRedis()
	defer red.Close()
	UnreadMap := make(map[string]int)
	// 使用 ZRANGEBYSCORE 命令获取 score 及对应的成员
	messages, _ := red.ZRangeByScoreWithScores("Unread"+Id, redis.ZRangeBy{Min: "-inf", Max: "+inf"}).Result()

	for i := 0; i < len(messages); i++ {
		ScoreStr := strings.Split(fmt.Sprintf("%f", messages[i].Score), ".")[0] //转型去掉小数点
		if _, ok := UnreadMap[ScoreStr]; !ok {                                  //统计 Sorted Set 中分数（score）出现次数
			UnreadMap[ScoreStr] = 1
		} else {
			UnreadMap[ScoreStr]++
		}
	}

	c.JSON(200, gin.H{
		"UnreadList": UnreadMap,
	})
}

// DelUnread 删除用户在reids中指定用户的未读消息
func DelUnread(c *gin.Context) {
	red, _ := DBconfing.ConnRedis()
	defer red.Close()
	Id := c.PostForm("Id")
	ToUid := c.PostForm("to_uid")
	red.ZRemRangeByScore("Unread"+Id, ToUid, ToUid)
	c.JSON(200, gin.H{
		"code":  200,
		"state": "ok",
	})
}

// AddBookingPlace 添加预约
func AddBookingPlace(c *gin.Context) {
	sqlDb, err := DBconfing.Mysql()
	defer sqlDb.Close()
	var BookingFrom model.Booking
	// 获取表单数据
	BookingFrom.StudentId, _ = strconv.Atoi(c.PostForm("stu_name"))
	BookingFrom.TeacherId, _ = strconv.Atoi(c.PostForm("teacher_name"))
	BookingFrom.BookingTime = c.PostForm("dateBooking")
	BookingFrom.Place = c.PostForm("place")
	BookingFrom.Content = c.PostForm("content")

	// 插入预约数据到数据库
	result, err := sqlDb.Exec("INSERT INTO booking (student_id, teacher_id, place,state,content,booking_time,create_time) VALUES (?, ?, ?, ?, ?, ?, ?)",
		BookingFrom.StudentId, BookingFrom.TeacherId, BookingFrom.Place, 1, BookingFrom.Content, BookingFrom.BookingTime, time.Now())
	if err != nil {
		c.JSON(200, gin.H{
			"code": 500,
			"msg":  "数据库出错啦~",
		})
		return
	}
	// 获取刚刚插入行的ID
	bookingId, err := result.LastInsertId()
	if err != nil {
		c.JSON(200, gin.H{
			"code": 500,
			"msg":  "获取ID出错啦~",
		})
		return
	}
	c.JSON(200, gin.H{
		"code":      200,
		"msg":       "预约成功",
		"bookingId": bookingId,
	})
}

// GetBookingPlace 获取预约地点
func GetBookingPlace(c *gin.Context) {
	sqlDb, _ := DBconfing.Mysql()
	defer sqlDb.Close()
	Id := c.Param("id")
	var bookingPlace string
	err := sqlDb.QueryRow("SELECT booking_place FROM teacher WHERE id = ?", Id).Scan(&bookingPlace)
	if err != nil {
		c.JSON(200, gin.H{
			"code": 500,
			"err":  err,
		})
		return
	}
	c.JSON(200, gin.H{
		"code":         200,
		"bookingPlace": bookingPlace,
	})
}
